using Gtk;

// GPL3

public class MainWindow : Window {
	Box box;
	
	public MainWindow () {
		this.title = "A";
		this.window_position = WindowPosition.CENTER;
		this.destroy.connect (main_quit);
		this.set_default_size (400, 300);
	
		setup_style ();

		setup_box ();

		add_title ("Hello world!");
		add_text (""" The acts of the mind, wherein it exerts its power over simple ideas, are chiefly these three: 1. Combining several simple ideas into one compound one, and thus all complex ideas are made. 2. The second is bringing two ideas, whether simple or complex, together, and setting them by one another so as to take a view of them at once, without uniting them into one, by which it gets all its ideas of relations. 3. The third is separating them from all other ideas that accompany them in their real existence: this is called abstraction, and thus all its general ideas are made.
""");
		add_title ("Hello solar system");
		add_text ("""I asked my 4 year old niece what are the ingredients in gravy and she answered with, "gravy". It kind of reminded me of programmers who use recursion to solve problems. When you use recursion you are essentially defining a procedure in terms of itself which makes no sense in the real world. Make believe stuff like this is why real scientist and engineers don't take computer scientist seriously.
""");


		add_title ("Worse is Better");
		add_subtitle ("Hello Subtitle!");
		add_text("""I and just about every designer of Common Lisp and CLOS has had extreme exposure to the MIT/Stanford style of design. The essence of this style can be captured by the phrase ``the right thing.'' To such a designer it is important to get all of the following characteristics right:""");
		add_list ("""Simplicity-the design must be simple, both in implementation and interface. It is more important for the interface to be simple than the implementation.""",
				  """Correctness-the design must be correct in all observable aspects. Incorrectness is simply not allowed.""",
				  """Consistency-the design must not be inconsistent. A design is allowed to be slightly less simple and less complete to avoid inconsistency. Consistency is as important as correctness.""",
				  """Completeness-the design must cover as many important situations as is practical. All reasonably expected cases must be covered. Simplicity is not allowed to overly reduce completeness.""");
		add_text("""I believe most people would agree that these are good characteristics. I will call the use of this philosophy of design the ``MIT approach.'' Common Lisp (with CLOS) and Scheme represent the MIT approach to design and implementation.""");

		add_image ("lisp.png");
	}

	void setup_style () {
		string style = """
GtkWindow {background-color:#ffffff;}
GtkTextView {background-color:#ffffff;}
GtkLabel {font-size: 24pt;}
GtkLabel.subtitle {font-size:16pt;}
""";
		CssProvider provider = new CssProvider ();
        try {
            provider.load_from_data (style,-1);
        } catch (GLib.Error e) {
            warning (e.message);
        }
        var screen = Gdk.Screen.get_default ();
        StyleContext.add_provider_for_screen (screen,provider,STYLE_PROVIDER_PRIORITY_USER);
	}

	void setup_box () {
		Box scrollable_box;
		ScrolledWindow scroll;

		scrollable_box = new Box (Orientation.VERTICAL, 0);

		scroll = new ScrolledWindow (null, null);
        scroll.set_policy (PolicyType.AUTOMATIC, PolicyType.AUTOMATIC);

		box = new Box (Orientation.VERTICAL, 0);

        scroll.add (box);
		scrollable_box.pack_start (scroll, true, true, 0);
		this.add (scrollable_box);

	}

	void add_title (string text) {
		Gtk.Label l = new Gtk.Label (text);
		l.set_halign (Gtk.Align.START);
		box.pack_start (l, false, false, 0);
	}

	void add_subtitle (string text) {
		Gtk.Label l = new Gtk.Label (text);
		l.set_halign (Gtk.Align.START);
		l.get_style_context ().add_class ("subtitle");
		box.pack_start (l, false, false, 0);
	}

	void add_text (string text) {
		TextView view = new TextView ();
		view.set_wrap_mode (WrapMode.WORD);
		view.buffer.text = text;
		view.set_editable (false);
		view.set_cursor_visible (false);
		box.pack_start (view, false, false, 0);
		
	}

	void add_list (...) {
		var l = va_list();
		while (true) {
			string? item = l.arg();
			if (item == null) {
				break;
			}
		    add_text ("• " + item);
		}
	}

	void add_image (string path) {
		Gtk.Image image = new Gtk.Image ();
		image.set_from_file (path);
		box.add (image);
	}
}

public class Application {
	public static int main (string[] args) {
		init (ref args);

		Window w = new MainWindow ();
		
		w.show_all ();
		
		Gtk.main ();

		return 0;
	}
}
